import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'

// 创建自定义的 axios 实例: service 对象
const service = axios.create({
    // 公共接口: url = base url + request url
    baseURL: process.env.VUE_APP_SERVER_URL,
    // baseURL: 'https://api.example.com',
    
    // 超时时间，单位是 ms。这里设置了 5s 的超时时间，超时后还没有响应则报错
    timeout: 5 * 1000
})

// 添加请求拦截器: request interceptor
service.interceptors.request.use(
	config => {
		// 发起请求前做一些处理，比如数据转化、配置请求头、设置 token、设置 loading 等，根据需求添加
		// 注意使用 token 的时候需要引入 cookie 方法或者用本地 localStorage 等方法，推荐 js-cookie
		if (store.getters.token) {
			// config.params = {'token': token}    // 若要求将 token 携带在 参数 params 中
			// config.headers.token = token;       // 若要求将 token 携带在 请求头 header 中
			// bearer: w3c规范
			config.headers['Authorization'] = 'Bearer ' + getToken()
		}
		return config
	},
	error => {
		// do something with request error
		return Promise.reject(error)
	}
)

// 设置 cross 跨域 并设置访问权限。允许跨域携带 cookie 信息，使用 JWT 时可关闭
service.defaults.withCredentials = false

// 添加响应拦截器: response interceptor
service.interceptors.response.use(
  	// 成功接收到响应数据后的一些共有的处理，比如关闭 loading 等 (2xx 范围内的状态码都会出发该函数。对响应数据做点什么)
	response => {
		// 获得响应中的数据 data
		const res = response.data
		// 若从后端返回的 ApiResult 的代码不是 200，则将其判断为登录失败 (错误)
		if (res.code !== 200) {
			// FIXME 看后端的 Api 异常处理
			// 若登录验证异常则跳转到 /login，比如 50008: 非法Token; 50012: 异地登录; 50014: Token失效等
			if (res.code === 401 || res.code === 50012 || res.code === 50014) {
				// 重新登录
				MessageBox.confirm('会话失效，您可以留在当前页面，或重新登录', '权限不足', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning',
					center: true
				})
				.then(() => {
					window.location.href = '#/login'
				})
			// 若是其他异常则直接提示
			} else { 
				Message({
					showClose: true,
					message: '⚠' + res.message || 'Error',
					type: 'error',
					duration: 3 * 1000
				})
			}
			return Promise.reject(new Error(res.message || 'Error'))
		// 若响应无错误则直接返回响应中的数据 data
		} else {
			return res
		}
	},
	error => {
		// 接收到异常响应的处理开始 (超出 2xx 范围的状态码都会触发该函数。对响应错误做点什么)
		Message({
			showClose: true,
			message: error.message,
			type: 'error',
			duration: 5 * 1000
		})
		return Promise.reject(error)
	}
)

// 导出自定义的 axios 实例
export default service